﻿using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using NUnit.Framework;

namespace com.bodurov.SessionRecovery.Tests
{
    [TestFixture]
    public class SerializationTestFixture
    {

        [Test]
        public void BasicSerialization()
        {
            const string FILENAME = "SessionRecovery.sess";
            if (File.Exists(FILENAME))
            {
                File.Delete(FILENAME);
            }
            var modelData = SampleData();
            IFormatter formatter = new BinaryFormatter();
            using (var stream = new FileStream(FILENAME, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
            {
                formatter.Serialize(stream, modelData);
                stream.Close();
            }

            Hashtable deserialized;
            using (var stream = new FileStream(FILENAME, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                deserialized = formatter.Deserialize(stream) as Hashtable;
                stream.Close();
            }
            Assert.IsNotNull(deserialized, "The Hashtable was not deserialized");
            Assert.AreEqual(modelData["SomeString"], deserialized["SomeString"]);
            Assert.AreEqual(modelData["SomeInt"], deserialized["SomeInt"]);
            var aModel = (A)modelData["SomeObject"];
            var aDeser = (A)deserialized["SomeObject"];
            Assert.IsNotNull(aDeser, "The object was not deserialized");
            Assert.AreEqual(aModel.Name, aDeser.Name);
            Assert.AreEqual(aModel.Number, aDeser.Number);
            Assert.IsNotNull(aDeser.SubObject, "Sub object was not deserialized");
            Assert.AreEqual(aModel.SubObject.Name, aDeser.SubObject.Name);
            Assert.AreEqual(aModel.SubObject.Number, aDeser.SubObject.Number);
        }

        #region Sample Data
        private static Hashtable SampleData()
        {
            return new Hashtable
                    {
                        {"SomeString", "Some string value"},
                        {"SomeInt", 111},
                        {"SomeObject", new A
                                           {
                                               Number = 1, 
                                               Name = "Obj A", 
                                               SubObject = new A
                                                             {
                                                                 Number = 2, 
                                                                 Name = "Sub Obj A"
                                                             }
                                           }}
                    };
        }
        #endregion

        [Serializable]
        public class A
        {
            public string Name { get; set; }
            public int Number { get; set; }
            public A SubObject { get; set; }
        }
    }
}
